package ren.kane.asdppp.affiliation;

import ren.kane.asdppp.Date;
import ren.kane.asdppp.transaction.cost.ServiceCharge;
import ren.kane.asdppp.transaction.pay.Paycheck;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.Map;

/**
 * @author renrk(1275) on 2019-04-18 8:45 PM
 **/
public class UnionAffiliation implements Affiliation {

    private int memberId;

    private double amount;

    private Map<LocalDate, ServiceCharge> serviceChargeMap = new HashMap<>();

    public UnionAffiliation() {
    }

    public UnionAffiliation(int memberId, double amount) {
        this.memberId = memberId;
        this.amount = amount;
    }

    public int getMemberId() {
        return memberId;
    }

    public double getAmount() {
        return amount;
    }

    @Override
    public ServiceCharge getServiceCharge(LocalDate date) {
        return serviceChargeMap.get(date);
    }

    public void addServiceCharge(LocalDate date, double charge) {
        serviceChargeMap.put(date, new ServiceCharge(date, charge));
    }

    @Override
    public double calculateDeductions(Paycheck paycheck) {
        double totalDues;
        int fridays = numberOfFridaysInPayPeriod(paycheck.getPayPeriodStartDate(), paycheck.getPayPeriodEndDate());
        totalDues = amount * fridays;
        for (Map.Entry<LocalDate, ServiceCharge> entry : serviceChargeMap.entrySet()) {
            if (Date.isBetween(entry.getKey(), paycheck.getPayPeriodStartDate(), paycheck.getPayPeriodEndDate())) {
                totalDues += entry.getValue().getCharge();
            }
        }
        return totalDues;
    }

    private int numberOfFridaysInPayPeriod(LocalDate payPeriodStart, LocalDate payPeriodEnd) {
        int fridays = 0;
        for (LocalDate day = payPeriodStart; !day.isAfter(payPeriodEnd); day = day.plusDays(1)) {
            if (day.getDayOfWeek().equals(DayOfWeek.FRIDAY)) {
                fridays++;
            }
        }
        return fridays;
    }
}
